package com.sensePlusVR.application;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import org.xutils.DbManager;
import org.xutils.x;
import org.xutils.ex.DbException;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Handler;

import com.jwaoo.android.JwaooBleToy.JwaooToyBatteryInfo;
import com.sensePlusVR.activity.guesture.GestureEditActivity;
import com.sensePlusVR.activity.guesture.GestureVerifyActivity;
import com.sensePlusVR.activity.listener.CPUInfoListener;
import com.sensePlusVR.activity.update.AppProgressActivity;
import com.sensePlusVR.bean.AppVersionInfo;
import com.sensePlusVR.bean.BuriePointActiveReqDto;
import com.sensePlusVR.bean.BuriePointEventReqDto;
import com.sensePlusVR.bean.CpuInfo;
import com.sensePlusVR.bean.GameItem;
import com.sensePlusVR.main.LoadingActivity;
import com.sensePlusVR.main.VrRealActivity;
import com.sensePlusVR.main.VrRealTestActivity;
import com.sensePlusVR.manager.BuriedPointManager;
import com.sensePlusVR.net.NetRequestManager;
import com.sensePlusVR.receiver.HomeListener;
import com.sensePlusVR.setting.bluetooth.BluetoothPlayer;
import com.sensePlusVR.setting.bluetooth.BluetoothPlayer.BTDataMsg;
import com.sensePlusVR.setting.bluetooth.BluetoothPlayer.BTEvent;
import com.sensePlusVR.utils.Constant;
import com.sensePlusVR.utils.ConstantURL;
import com.sensePlusVR.utils.DateTimeUtil;
import com.sensePlusVR.utils.FileUtils;
import com.sensePlusVR.utils.GameDownload;
import com.sensePlusVR.utils.MyLog;
import com.sensePlusVR.utils.MyPageJump;
import com.sensePlusVR.utils.MySharedPreferences;
import com.sensePlusVR.utils.SystemProperty;
import com.sensePlusVR.utils.UnDistortionUtil;
import com.sensePlusVR.utils.UserUtil;
import com.sensePlusVR.utils.VersionUtil;
import com.sensePlusVR.utils.VersionUtil.CheckVersion;
import com.sensePlusVR.widget.dialog.AppVersionTipDialog;
import com.umeng.analytics.MobclickAgent;
import com.umeng.analytics.MobclickAgent.EScenarioType;
import com.umeng.commonsdk.UMConfigure;

public class VRApplication extends Application{
	
	
	private static final String TAG = VRApplication.class.getSimpleName();
	
	private static VRApplication instance;
	private static DbManager.DaoConfig daoConfig;// 数据库初始化
	protected static DbManager db;
	public static final String DB_NAME = "sensePlusVR.db";
	
	public final static String SLEEP_INTENT = "org.videolan.vlc.SleepIntent";
	public final static String INCOMING_CALL_INTENT = "org.videolan.vlc.IncomingCallIntent";
	public final static String CALL_ENDED_INTENT = "org.videolan.vlc.CallEndedIntent";
	
	private BluetoothPlayer mBluetoothPlayer;
	
	//版本信息
	private AppVersionInfo mNewAppVersionInfo;
	
	//activity数量
	private int activityCount = 0;
	
	private Timer mTimer;
	
	private TimerTask mTimerTask;
	
	private static final long timeDelay = 1000*2;
	
	private boolean isShowGesture = true;
	
	private CheckVersion mCheckVersionForAc;
	
	private boolean mHasAccelSensor=true;
	private boolean mHasGravSensor=true;
	private boolean mHasGyroSensor=true;
	
	private Activity curActivity;
	
	//共享变量,为了处理两个Activity或者Fragment之间发消息
	public static Map<String, Handler> handlers = new HashMap<String, Handler>();
	
	
	@Override
	public void onCreate() {
		super.onCreate();
		
		MyLog.d(TAG, "VRApplication create....");
		instance = this;
		SensorManager sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
		Sensor sense=sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
		MyLog.e(TAG, "gyroscope="+sense);
		if (sense == null){
			mHasGyroSensor = false;
		}
		sense=sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
		MyLog.e(TAG, "acc="+sense);
		if (sense == null){
			mHasAccelSensor = false;
		}
		
		sense=sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
		MyLog.e(TAG, "grav="+sense);
		if (sense == null){
			mHasGravSensor = false;
		}
		
		initDb();
			
		//检查http
		ConstantURL.checkURL(this);
		
		initUmengSDK();
		
		MyLog.checkLog(this);
		
		getCPUInfo();
	
		
		//检查版本更新
		VersionUtil.checkoutVersion(this,mCheckVersion);
		
		//增加畸变
		UnDistortionUtil.checkDistortion(this);
		
		//上传埋点信息
		BuriedPointManager.getInstants().uploadAllBuriedPointToService();
		
		//初始化GameDownload模块
		GameDownload.init(instance);
		
		//重新下载(内部包含游戏更新情况)
		GameDownload.reDownloadGame();
		
		registerActivityLifecycleCallbacks(new MyActivityLifecycleCallbacks());
	
		mBluetoothPlayer = new BluetoothPlayer(this); 
		
		mTimer = new Timer();
	
		tryConnectBT();
		
	}
	
	
	private void initUmengSDK() {
		/** 初始化Umeng通用接口(Umeng暂时不支持动态改变Channel id,如果设备安装过一次后即使写在还是最初的Channel id)*/
		UMConfigure.init(this, UMConfigure.DEVICE_TYPE_PHONE, null);
		MyLog.d(TAG, "init appKey : " + Constant.VALUE_UMENG_APPKEY);
		MyLog.d(TAG, "init channel id : " + ConstantURL.VALUE_CHANNEL_ID);
		/** 设置是否对日志信息进行加密, 默认false(不加密). */
		MobclickAgent.enableEncrypt(true);
		/** 打开调试模式 */
		MobclickAgent.setDebugMode( true );
		/** 禁止默认的页面统计方式，这样将不会自动统计Activity(因为存在Activity中嵌套Fragment,为了不区分对待，所以此处屏蔽掉，然后在BaseActivity中添加) */
		MobclickAgent.openActivityDurationTrack(false);
		/*设置场景类型*/
		MobclickAgent.setScenarioType(this, EScenarioType.E_UM_NORMAL);
		/*代码设置appKey、channel id及场景类型*/
        //MobclickAgent.startWithConfigure(
        //new UMAnalyticsConfig(this, Constant.VALUE_UMENG_APPKEY, ConstantURL.VALUE_CHANNEL_ID,
        //EScenarioType.E_UM_NORMAL));
		 /*设置是否允许收集地理位置信息 （默认true）*/
        // MobclickAgent.setAutoLocation(true);
		/*设置session启动的沉默参数，详见30秒规则 （默认30000）*/
        // MobclickAgent.setSessionContinueMillis(1000);
	}


	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		MyLog.d(TAG, "onConfigurationChanged fontScale : " + newConfig.fontScale);
		 if (newConfig.fontScale != 1)//非默认值
		        getResources();   
		super.onConfigurationChanged(newConfig);
	}
	
	@Override
	public Resources getResources() {
		MyLog.d(TAG, "getResources...");
		Resources res = super.getResources();
	     if (res.getConfiguration().fontScale != 1) {//非默认值
	        Configuration newConfig = new Configuration();       
	        newConfig.setToDefaults();//设置默认        
	        res.updateConfiguration(newConfig, res.getDisplayMetrics()); 
	     }    
	     return res;
	}
	
	public static VRApplication getInstance(){
		return instance;
	}
	
	public CpuInfo getCPUInfo() {
		CpuInfo cpuInfo = CpuInfo.getCPUInfo();
		if(cpuInfo != null){
			MyLog.d(TAG, "cpuInfo : " + cpuInfo.toString());
			return cpuInfo;
		}
		
		try {
			String cpuNameDecode = URLDecoder.decode(SystemProperty.getCpuName(),"UTF-8");
			MyLog.d(TAG, "cpuNameDecode : " + cpuNameDecode);
			NetRequestManager.startCPUInfo(instance, cpuNameDecode,cpuInfoListenerFirst);
			
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return null;
		}
		return null;
	}
	
	private CPUInfoListener cpuInfoListenerFirst = new CPUInfoListener() {
		
		@Override
		public void onCPUInfoListener(CpuInfo cpuInfo) {
			MyLog.d(TAG, "cpuInfoListenerFirst cpuInfo : " + cpuInfo);
			if(cpuInfoListenerOther != null){
				cpuInfoListenerOther.onCPUInfoListener(cpuInfo);
			}
		}
	};
	
	private CPUInfoListener cpuInfoListenerOther;
	
	public void setCPUInfoCallback(CPUInfoListener cpuInfoListenerOther){
		this.cpuInfoListenerOther = cpuInfoListenerOther;
	}
	
	

	protected void initDb() {
		
		//检查是否需要数据库更新
		x.Ext.init(instance); // xUtils 初始化
		x.Ext.setDebug(true); // 输出日志
		// 本地数据的初始化
		daoConfig = new DbManager.DaoConfig().setDbName(DB_NAME)// 设置数据库名
				//.setDbDir(null)//数据库存储路径，不写则为默认路径(默认为包名下databases目录下)
				//.setDbDir(new File(FileUtils.getSDcardDir() + File.separator + "AADB"))
				.setDbVersion(Constant.dbVersion) // 设置数据库版本,每次启动应用时将会检查该版本号,发现数据库版本低于这里设置的值将进行数据库升级并触发DbUpgradeListener
				.setAllowTransaction(true)// 设置是否开启事务,默认为false关闭事务
				// 设置数据库创建时的Listener
				.setDbUpgradeListener(new DbManager.DbUpgradeListener() {
					@Override
					public void onUpgrade(DbManager db, int oldVersion,
							int newVersion) {
						MyLog.d(TAG, "onUpgrade...newVersion="+newVersion+" oldVersion="+oldVersion);
						if(newVersion>oldVersion){
							if(newVersion == 12){
								MySharedPreferences.saveObject(instance,Constant.USER_FOLLOW_IDS,null);
							}
							if(oldVersion < 8){
								MyLog.d(TAG, "update sqlite...");
								//version = 8 删除所有数据
								removeLocalData(db);
							}else if(oldVersion == 8 || oldVersion == 9){
								try {
									db.dropTable(GameItem.class);
								} catch (DbException e) {
									MyLog.d(TAG, "dropTable failed...");
								}
							}else if(oldVersion == 10){
								try {
									db.addColumn(BuriePointEventReqDto.class,"state");
								} catch (DbException e) {
									MyLog.d(TAG, "addColumn failed...");
								}
							}
						}
					}
				});
		db = x.getDb(daoConfig);
		
	}
	
	/**
	 * 清除本地除了手势及用户名信息的其他资源
	 */
	private void removeLocalData(DbManager db){
		// 删除本地所有的形式一存储的Sharedpreferences（像手势密码用户名等信息通过方法二存储，所以只能用removeFile2方法删除掉）
		MySharedPreferences.removeFile(instance);
			// 删除所有本地数据库
		try {
			db.dropDb();// 删除整个数据库
			// db.addColumn(GameItem.class,"aaa");//给GameItem数据库添加字段aaa
			// db.dropTable(GameItem.class);//删除整个GameItem数据库
		} catch (DbException e) {
			MyLog.d(TAG, "removeLocalData failed...");
		}
		// 删除沙河所有资源文件
		FileUtils.deleteFile(FileUtils
					.getExternalDir(instance));
	}
	
	/**
	 * @return the main context of the Application
	 */
	public static Context getAppContext() {
		return instance;
	}

	public static DbManager getDbManager(){
		return db;
	}
	public static DbManager.DaoConfig getDaoConfig() {

		return daoConfig;

	}
	
	/**
	 * If this device support accelerometer sensor
	 */
	public boolean HasAccelSensor(){
		return mHasAccelSensor;
	}
	
	/**
	 * If this device support gravity sensor
	 */
	public boolean HasGravSensor(){
		return mHasGravSensor;
	}
	
	/**
	 * If this device support Gyroscope sensor
	 */
	public boolean HasGyroSensor(){
		return mHasGyroSensor;
	}
	
	/**
	 * @return the main resources from the Application
	 */
	public static Resources getAppResources() {
		return instance.getResources();
	}
	
	
	public void tryConnectBT(){
		
		new Thread(){
			public void run() {
				//macAdder
				String macAdr = MySharedPreferences.getString(VRApplication.this, Constant.SP_BLUE_ADDRESS);
				
				MyLog.d(TAG, "macAdr : " + macAdr);
				if(macAdr!=""){
					tryConnectBT(macAdr);
				}	
			};
		}.start();
	}

	/**
	 * 连接蓝牙
	 * @param macAddr
	 */
	public void tryConnectBT(final String macAddr){
		new Thread(){
			public void run() {
				mBluetoothPlayer.connect(macAddr);
			};
		}.start();
	}
	//设置蓝牙回调事件
	public void setBTEvent(BTEvent onBTEvent){
		
		mBluetoothPlayer.setBTEvent(onBTEvent);
	}
	
	public boolean isBTConnected(){
		
		return mBluetoothPlayer.isBTConnected();
	}
	
	//是否上报数据
	public void setSensorEnable(final boolean enable){
			new Thread(){
				public void run() {
					mBluetoothPlayer.setSensorEnable(enable);
				};
			}.start();
	}
	
	//是否上报数据
	public void setSensorEnable(final boolean enable,final BTDataMsg onBTDataMsg){
		new Thread(){
			public void run() {
				mBluetoothPlayer.setSensorEnable(enable, onBTDataMsg);
			};
		}.start();
	}
	
	public boolean isSupportFovKey(){
		return mBluetoothPlayer.isSupportFovKey();
	}
	
	/**
	 * 断开蓝牙连接
	 */
	public void toBTDisconnect(){
		new Thread(){
			public void run() {
				mBluetoothPlayer.toBTDisconnect();
			};
		}.start();
	}
	
	
	/**
	 * 注册蓝牙广播
	 */
	public void registerBT(){
		
		mBluetoothPlayer.registerBT();
		
	}
	
	/**
	 * 取消注册蓝牙广播
	 */
	public void unregisgerBT(){
		
		mBluetoothPlayer.unregisterBT();
	}
	
	/**
	 * 获取电池电量
	 * @return
	 */
	public int getBatteryLevel(){
		
		String macAdr = MySharedPreferences.getString(this, Constant.SP_BLUE_ADDRESS);
		
		JwaooToyBatteryInfo batterInfo = mBluetoothPlayer.getBatteryInfo(macAdr);
		int level = 0;
		if(batterInfo == null){
			return 0;//没有连接上则返回 0
		}
		level = batterInfo.getLevel();
		return level;
		
	}
	
	/**
	 * 获取蓝牙设备 id
	 * @return
	 */
	public int getDeviceId(){
		return mBluetoothPlayer.getDeviceId();
	}
	
	/**
	 * 获取蓝牙设备Mac地址
	 * @return
	 */
	public String getDeviceAddress(){
		return mBluetoothPlayer.getDeviceAddress();
	}
	
	/**
	 * 获取蓝牙设备版本号
	 * @return
	 */
	public int getDeviceVersion(){
		return mBluetoothPlayer.getDeviceVersion();
	}
	
	//获取新的版本信息
	public AppVersionInfo getNewVersionInfo(){
		
		return mNewAppVersionInfo;
	}
	
	//设置版本回调
	public void setCheckVersionCallback(CheckVersion checkVersion){
		
		this.mCheckVersionForAc = checkVersion;
	}
	
	//版本检查回调
	private CheckVersion mCheckVersion = new CheckVersion() {
		
		@Override
		public void onVersionCallback(AppVersionInfo appVersionInfo) {
			
			if(appVersionInfo!=null){
				
				MyLog.d(TAG, appVersionInfo.toString());
				
				mNewAppVersionInfo = appVersionInfo;
				
				if(mCheckVersionForAc!=null){
					//针对非强制升级只在启动时候展示,设置回调的情况
					mCheckVersionForAc.onVersionCallback(mNewAppVersionInfo);
					
					return;
				}
				
				//强制升级再按Home后从新进入界面展示
				checkNewVersion(mNewAppVersionInfo);
				
			}
			
			
		}
	};
	
	private void checkNewVersion(AppVersionInfo newAppVersionInfo){
		MyLog.d(TAG, "checkNewVersion...");
		String curVersionName = VersionUtil.getVersionName(this);
		String versionCode = newAppVersionInfo.getVersioncode();
		MyLog.d(TAG, "versionCode : " + versionCode);
		if(/*savedInstanceState==null&&*/VersionUtil.canVersionUpdate(newAppVersionInfo.getVersonname(), curVersionName)){
			if(versionCode.contains("force update")){
				MyLog.d(TAG, "force update...");
				if(curActivity == null)return;
				//不在以下Activity中展示强制升级界面
				String curClassName = curActivity.getClass().getName();
				if(curClassName.equals(VrRealActivity.class.getName())
						|| curClassName.equals(VrRealTestActivity.class.getName()) 
						|| curClassName.equals(AppProgressActivity.class.getName())){
					return;
				}
				AppVersionTipDialog appVersionTipDlg = new AppVersionTipDialog(curActivity,newAppVersionInfo,false,true);
				appVersionTipDlg.show();
				return;
			}
		}
	}
	
	
	private BuriePointActiveReqDto appActiveReqDto;
	
	private class MyActivityLifecycleCallbacks implements ActivityLifecycleCallbacks{
		private long startTime = 0;
		
		public MyActivityLifecycleCallbacks(){
			if(appActiveReqDto == null){
				initAppActive();
			}
			
			
		}
		
		private void initAppActive(){
			appActiveReqDto = new BuriePointActiveReqDto();
			appActiveReqDto.setUid(UserUtil.getUserId());
			long timeL = System.currentTimeMillis();
			startTime = timeL;
			String timeStr = DateTimeUtil.getStandTime(timeL);
			appActiveReqDto.setStart_time(timeStr);
			
		}
		
		@Override
		public void onActivityStopped(Activity activity) {
			MyLog.d(TAG, "onActivityStopped...");
			long timeL = System.currentTimeMillis();
			long duration = timeL - startTime;
			String timeStr = DateTimeUtil.getStandTime(timeL);
			appActiveReqDto.setEnd_time(timeStr);
			appActiveReqDto.setDuration(duration);
			BuriePointActiveReqDto.saveOrUpdate(appActiveReqDto);
			
		}
		
		@Override
		public void onActivityStarted(Activity activity) {
			// TODO Auto-generated method stub
			
			
			
					
			
		}
		
		@Override
		public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
			// TODO Auto-generated method stub
			
		}
		
		@Override
		public void onActivityResumed(Activity activity) {
			
			curActivity = activity;
			
			if(mTimerTask!=null){
				
				
				mTimerTask.cancel();
				
				mTimerTask = null;
				
			}
			
			activityCount++;
			
			String inputCode = MySharedPreferences.getString2(getApplicationContext(),MySharedPreferences.NAME_NOT_CLEAR,Constant.SP_INPUTCODE);
				
			
			String curClassName = activity.getClass().getName();
			
			
			if(inputCode!=""&&isShowGesture){
				if(!curClassName.equals(GestureVerifyActivity.class.getName())&&!curClassName.equals(GestureEditActivity.class.getName())&&!curClassName.equals(LoadingActivity.class.getName())){
					MyLog.d(TAG, "pageJump GestureVerifyActivity");
					MyPageJump.pageJumpAddBoolean(activity, GestureVerifyActivity.class,Constant.INTENT_GUESTURE_RESET_NOT,true);
				}
					
			}

			
			//是否显示强制升级
			boolean isHomeClick = HomeListener.isHomeClick;
			MyLog.d(TAG, "isHomeClick : " + isHomeClick);
			if(isHomeClick){
 				
				VersionUtil.checkoutVersion(activity,mCheckVersion);
				
				HomeListener.isHomeClick = false;
			}
			
			MyLog.d(TAG, "activityCount++="+activityCount);
			
		}
		
		
		@Override
		public void onActivityPaused(Activity activity) {
			
			// TODO Auto-generated method stub
			activityCount--;
			
			MyLog.d(TAG, "activityCount--="+activityCount);
			
			if(activityCount==0 && !activity.getClass().getName().equals(LoadingActivity.class.getName())){
				
				
				isShowGesture = false;
				
				mTimerTask = new TimerTask() {
					
					@Override
					public void run() {
						
						isShowGesture = true;
						
						MyLog.d(TAG, "Time is up!");
						
					}
				};
				
				
				mTimer.schedule(mTimerTask, timeDelay);
				
			}
			
		}
		
		@Override
		public void onActivityDestroyed(Activity activity) {
			// TODO Auto-generated method stub
			
		}
		
		
		@Override
		public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
			// TODO Auto-generated method stub
			
		}
	
		
	}
	
	public boolean getShowGesture(){
		return isShowGesture;
	}
	
}
